﻿using ITSparta.Collections;
using ITSparta.MVVM;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;

namespace SPConfigDBReaderApp.ViewModels
{
    public class ClassViewModel : ViewModelBase
    {
        #region Fields

        private MTObservableCollection<ClassViewModel> _childClasses = new MTObservableCollection<ClassViewModel>();
        private MTObservableCollection<ObjectViewModel> _objects = new MTObservableCollection<ObjectViewModel>();
        private bool _isSelected = false;
        private bool _isExpanded = false;
        private bool _isLoaded = false;
        private bool _isActivted = false;

        #endregion

        #region Properties

        public Guid Id { get; private set; }
        public Guid BaseClassId { get; private set; }
        public string FullName { get; private set; }
        public string Assembly { get; private set; }
        public string Name { get; private set; }
        public string ClassName { get; private set; }

        public bool IsRoot { get { return Id == BaseClassId; } }
        public ClassViewModel BaseClass { get; private set; }
        public MTObservableCollection<ClassViewModel> ChildClasses
        {
            get
            {
                return _isActivted ? _childClasses : null;
            }
        }
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value)
                {
                    _isActivted = true;
                    OnPropertyChanged("ChildClasses");

                    MainWindowViewModel.Current.SelectedClass = this;
                }
                _isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
        public bool IsExpanded { get { return _isExpanded; } set { _isExpanded = value; OnPropertyChanged("IsExpanded"); } }
        public int Count { get { return _childClasses.Count; } }
        public MTObservableCollection<ObjectViewModel> Objects { get { return _objects; } }
        public IEnumerable<ClassViewModel> Bases
        {
            get
            {
                var c = this;
                while (c != null)
                {
                    yield return c;

                    c = c.BaseClass;
                }
                yield break;
            }
        }

        #endregion

        #region Constructor

        internal ClassViewModel(SqlDataReader reader)
        {
            Id = (Guid)reader["Id"];
            BaseClassId = (Guid)reader["BaseClassId"];
            FullName = (string)reader["FullName"];

            var temp = FullName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            Assembly = temp[1].Trim();
            Name = temp[0].Trim();

            temp = Name.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            ClassName = temp[temp.Length - 1];

            if (IsRoot)
                _isActivted = true;
        }

        #endregion

        #region Methods

        internal void Init()
        {
            if (_isLoaded)
                return;
            _isLoaded = true;

            if (!IsRoot)
            {
                ClassViewModel baseClass = null;
                if (!MainWindowViewModel.Current.TryGetClass(BaseClassId, out baseClass))
                    throw new Exception();
                BaseClass = baseClass;
            }

            var temp = new List<ClassViewModel>();
            foreach (var c in MainWindowViewModel.Current.Classes)
            {
                if (c.BaseClassId != Id || c.IsRoot)
                    continue;

                temp.Add(c);
            }

            foreach (var c in temp.OrderBy(it => it.ClassName))
                _childClasses.Add(c);
        }

        #endregion
    }
}